package cn.zzdt4j.auth.service.impl;

import cn.zzdt4j.auth.service.LdapService;
import cn.zzdt4j.server.common.base.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

/**
 * Ldap service impl.
 *
 * @author by <a href="mailto:ligang941012@gmail.com">gang.Li</a>
 * @since 2023/10/30 0:27
 */
@Service
@Slf4j
public class LdapServiceImpl implements LdapService {

    private final LdapTemplate ldapTemplate;

    @Value("${spring.ldap.object-class:}")
    private String objectClassName;

    @Value("${spring.ldap.account-attribute:}")
    private String accountAttribute;

    public LdapServiceImpl(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    @Override
    public void login(String username, String password) {
        try {
            ldapTemplate.authenticate(LdapQueryBuilder.query()
                    .where(accountAttribute).is(username)
                    .and(query().where("objectClass").is(objectClassName)), password);
            log.debug("{} ldap Login successful", username);
        } catch (EmptyResultDataAccessException e) {
            throw new UsernameNotFoundException("ldap Can't find the user information ");
        } catch (AuthenticationException e) {
            log.debug("The user name or account error");
            throw new BadCredentialsException("The username or password error");
        } catch (UncategorizedLdapException e) {
            log.debug("Please check whether the user name password input");
            throw new BadCredentialsException("Please check whether the username password input");
        } catch (Exception e) {
            throw new ServiceException("Abnormal server");
        }
    }
}
